package com.jdk.demo.thread.completableFuture;

import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ExecutionException;
import java.util.function.Function;
import java.util.function.Supplier;

// thenCompose方法允许你对两个CompletionStage进行流水线操作，第一个操作完成时，将其结果作为参数传递给第二个操作
// 考虑下面的例子：
// 函数1：输入userId，返回user对象。但由于是异步调用，所以返回了一个CompletableFuture<User>对象。
// 函数2：输入user对象，获取该user的信用卡积分（Double类型）。由于是异步调用，返回的不是Double，而是CompletableFuture<Double>。
// 这两个函数链式调用，代码如下所示：CompletableFuture<CompletableFuture<Double>> result = getUserDetail(userId).thenApply(user -> getCreditRating(user))
// 因为函数 getCreditRating(user)返回的是一个 CompletableFuture<Double>类型，所以在链式调用之后，返回值变成一个嵌套的数据类型CompletableFuture<CompletableFuture<Double>>。
// 如果希望返回值是一个展平的CompletableFuture，可以使用thenCompose
public class ThenComposeDemo {

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		CompletableFuture<Integer> f = CompletableFuture.supplyAsync(new Supplier<Integer>() {
            @Override
            public Integer get() {
                int t = new Random().nextInt(3);
                System.out.println("t1="+t);
                return t;
            }
        })
		.thenCompose(new Function<Integer, CompletionStage<Integer>>() {
            @Override
            public CompletionStage<Integer> apply(Integer param) {
                return CompletableFuture.supplyAsync(new Supplier<Integer>() {
                    @Override
                    public Integer get() {
                        int t = param *2;
                        System.out.println("t2="+t);
                        return t;
                    }
                });
            }

        });
        System.out.println("thenCompose result : " + f.get());
	}

}
